/*
 * TimeShift.cpp
 *
 *  Created on: 2020年6月19日
 *      Author: chuanjiang.zh
 */

#include "TimeShift.h"

#define AV_NOPTS_VALUE          ((int64_t)UINT64_C(0x8000000000000000))


TimeShift::TimeShift():
	m_frameDuration(40000),
	m_frameGap(5),
	m_gapDuration(m_frameDuration * m_frameGap),
	m_rawTs(AV_NOPTS_VALUE),
	m_prevOutTs(0),
	m_tuneEnabled()
{
}

TimeShift::~TimeShift()
{
}

void TimeShift::reset()
{
	m_rawTs = AV_NOPTS_VALUE;
	m_prevOutTs = 0;
}

int64_t TimeShift::shift(int64_t ts, int64_t& duration, int* status)
{
	int64_t newTs = 0;
	if (ts == AV_NOPTS_VALUE || m_rawTs == AV_NOPTS_VALUE)
	{
		duration = m_frameDuration;
		newTs = m_prevOutTs + m_frameDuration;

		if (status)
		{
			*status = STATUS_INVALID;
		}

		m_prevOutTs = newTs;
		m_rawTs = ts;
	}
	else
	{
		int64_t offset = ts - m_rawTs;
		if (offset <= 0)
		{
			duration = m_frameDuration;
			newTs = m_prevOutTs + m_frameDuration;
			if (status)
			{
				*status = STATUS_BACKWARD;
			}
		}
		else if (offset > m_gapDuration)
		{
			duration = m_frameDuration;
			newTs = m_prevOutTs + m_frameDuration;

			if (status)
			{
				*status = STATUS_LEAP;
			}
		}
		else
		{
			duration = offset;
			newTs = m_prevOutTs + offset;

			if (m_tuneEnabled)
			{
				m_frameDuration = (m_frameDuration + offset) / 2;
				m_gapDuration = (m_frameDuration * m_frameGap);
			}
		}

		m_prevOutTs = newTs;
		m_rawTs = ts;
	}

	return newTs;
}

void TimeShift::setFrameDuration(int64_t duration)
{
	if (duration < 0)
	{
		return;
	}

	m_frameDuration = duration;
	m_gapDuration = m_frameDuration * m_frameGap;
}

void TimeShift::setFrameGap(int count)
{
	if (count <= 1)
	{
		return;
	}

	m_frameGap = count;
	m_gapDuration = m_frameDuration * m_frameGap;
}

void TimeShift::enableTune(bool enabled)
{
	m_tuneEnabled = enabled;
}